[Relay][Prelude] Use the Relay parser to define the Relay prelude - #3043
Conversation
|
AFAICT relay dont has a way of defining adt. |
|
Finalizing a Relay ADT syntax would be of great help to docs too |
| if mod is None: | ||
| mod = Module({}) | ||
|
|
||
| file = os.path.join(__PRELUDE_PATH__, "prelude.rly") |
| return type_param | ||
|
|
||
| raise ParseError("Unknown builtin type: {}".format(ident_type)) | ||
| print(type_ident) |
| return None | ||
|
|
||
| def visitIdentType(self, ctx): | ||
| # TODO(@jroesch) Identifier Type doesn't make sense should be Type Identifier. |
There was a problem hiding this comment.
Can we resolve this TODO in this PR?
joshpoll
left a comment
There was a problem hiding this comment.
Please bump the version number.
|
|
||
| func: 'fn' '(' argList ')' ('->' type_)? body ; | ||
| defn: 'def' ident '(' argList ')' ('->' type_)? body ; | ||
| func: 'fn' (typeParamSeq)? '(' argList ')' ('->' type_)? body ; |
There was a problem hiding this comment.
| func: 'fn' (typeParamSeq)? '(' argList ')' ('->' type_)? body ; | |
| func: 'fn' typeParamSeq? '(' argList ')' ('->' type_)? body ; |
| func: 'fn' '(' argList ')' ('->' type_)? body ; | ||
| defn: 'def' ident '(' argList ')' ('->' type_)? body ; | ||
| func: 'fn' (typeParamSeq)? '(' argList ')' ('->' type_)? body ; | ||
| defn: 'def' ident (typeParamSeq)? '(' argList ')' ('->' type_)? body ; |
There was a problem hiding this comment.
| defn: 'def' ident (typeParamSeq)? '(' argList ')' ('->' type_)? body ; | |
| defn: 'def' ident typeParamSeq? '(' argList ')' ('->' type_)? body ; |
| // currently unused | ||
| // | identType '[' (type_ (',' type_)*)? ']' # callType | ||
| | 'fn' '(' (type_ (',' type_)*)? ')' '->' type_ # funcType | ||
| | 'fn' (typeParamSeq)? '(' (type_ (',' type_)*)? ')' '->' type_ # funcType |
There was a problem hiding this comment.
| | 'fn' (typeParamSeq)? '(' (type_ (',' type_)*)? ')' '->' type_ # funcType | |
| | 'fn' typeParamSeq? '(' (type_ (',' type_)*)? ')' '->' type_ # funcType |
|
@jroesch has asked me to take over this PR so I will work on addressing feedback and fixing linting errors to get this to a mergeable state soon. The next step would be to add ADTs and matching to the text format so the entire prelude can be written in the text format (I think that should be a separate PR) |
|
Pinging reviewers: @wweic @joshpoll @MarisaKirisame |
| grammar Relay; | ||
|
|
||
| SEMVER: 'v0.0.1' ; | ||
| SEMVER: 'v0.0.1.1' ; |
There was a problem hiding this comment.
| SEMVER: 'v0.0.1.1' ; | |
| SEMVER: 'v0.0.2' ; |
This is the convention for pre-release semver.
| typeParamSeq | ||
| : '[' ']' | ||
| | '[' ident ']' | ||
| | '[' ident (',' ident)+ ']' |
There was a problem hiding this comment.
| | '[' ident (',' ident)+ ']' | |
| | '[' ident (',' ident)* ']' |
to merge this case and the previous one.
There was a problem hiding this comment.
tuples need something different b/c they require a trailing comma
| typeParamSeq | ||
| : '[' ']' | ||
| | '[' ident ']' | ||
| | '[' ident (',' ident)+ ']' |
There was a problem hiding this comment.
tuples need something different b/c they require a trailing comma
| raises_parse_error = lambda x: x | ||
|
|
||
| SEMVER = "v0.0.1" | ||
| SEMVER = "v0.0.1.1" |
There was a problem hiding this comment.
| SEMVER = "v0.0.1.1" | |
| SEMVER = "v0.0.2" |
| def visitTypeIdent(self, ctx): | ||
| ''' | ||
| Handle type identifier. | ||
| type: (RelayParser.TypeIdentContext) -> Union[ty.TensorType, str] |
There was a problem hiding this comment.
this type annotation should be # type: (RelayParser.IdentTypeContext) -> Union[ty.TensorType, str] and go above and outside the doc string. cf: https://mypy.readthedocs.io/en/latest/cheat_sheet.html
There was a problem hiding this comment.
Pylint complained when I had it that way
There was a problem hiding this comment.
Ah, it complained because I had the annotation after the docstring, not before
| return ty.scalar_type(type_ident) | ||
|
|
||
| type_param = lookup(self.type_param_scopes, type_ident) | ||
| if type_param: |
There was a problem hiding this comment.
| if type_param: | |
| if type_param is not None: |
| __PRELUDE_PATH__ = os.path.dirname(os.path.realpath(__file__)) | ||
|
|
||
| def load_prelude(mod=None): | ||
| '''Parses the portions of the Prelude written in Relay's text format and adds |
There was a problem hiding this comment.
newline after '''. Consider using either ''' or """ for all docstrings in this file
91fa672 to
57557ae
Compare
|
Thanks for the feedback. I also removed |
|
Fixing the previous test failure led me to realize that we have an issue with the parser flag: If we want to have the Prelude and other important Relay functionality written using the text format, should the parser be an optional flag? I changed the prelude to check whether the parser is enabled and default to the old manually written ASTs, but this does not seem like a particularly good practice, since it requires us to maintain two definitions, one of which is indeed a manually assembled AST. What do you all believe is a good approach moving forward? (addressed to the reviewers, also @jroesch and @tqchen) |
|
We should conditionally support generating the parser, when we check in we should generate a copy, commit it, and mark the files as binaries in my opinion, it satisfies both design tensions. |
|
I agree that there should be a pre-generated parser available for users who do not intend to modify the grammar or parser. It would be good not to have to introduce ANTLR as a mandatory dependency for users who want to use Relay's text format. Does everyone agree that we should have a pre-generated parser committed and marked as a binary? |
|
I've now added the parser to the repo so users can always run the parser, even if they don't have ANTLR enabled in their build. It will be easy to revert that commit if this choice is objectionable |
|
I think having a pre-generated parser is a good idea, it will also enable running text format unit test for every tvm user without ANTLR installed. |
|
Would appreciate input from anyone knowledgeable whether the generated parser files should have the Apache headers on them (we'd need to script for them to be appended during the build if so) |
| @@ -0,0 +1,209 @@ | |||
| # Generated from /home/sslyu/tvm/python/tvm/relay/grammar/Relay.g4 by ANTLR 4.7.2 | |||
There was a problem hiding this comment.
Can you mark these all as binary files?
There was a problem hiding this comment.
I did in .gitattributes, but it didn't change how they display on Github. I will try this as well: https://help.github.com/en/articles/customizing-how-changed-files-appear-on-github
|
|
||
| def test_int_literal(): | ||
| assert isinstance(relay.fromtext(SEMVER+"1"), relay.Constant) | ||
| assert isinstance(relay.fromtext(SEMVER+"1").data, tvm.ndarray.NDArray) |
There was a problem hiding this comment.
I know this isn't the point of this PR, but can we have relay.fromtext(SEMVER + _) as a helper function for this test file? It's a bit of an eye sore.
|
No idea what's with the test failure but it definitely appears unrelated |
cfc05e6 to
76e8006
Compare
…naries, and have parser tests always fire
76e8006 to
6e08ad5
Compare
…ache#3043) * Add ability to load Prelude from disk * Port over id * Define compose * Linting errors and style changes * Eliminate unnecessary parens * Rename identType to typeIdent (makes more sense) * Another unnecessary paren * Bump the version number for the text format * Ensure .rly (Relay text files) are permitted * Correct release number and simplify grammar rule * Correct load_prelude docstring * Corrections to _parser * Add Apache headers to prelude source file * Remove test_prelude (redundant) * Correct misleading error message * Add check that parser is enabled in Prelude * Commit pre-generated parser, ensure generated files are treated as binaries, and have parser tests always fire * Permit parser files and git attributes files * Exclude gitattributes and parser files from apache check * Another attempt at appeasing Apache audit checker * Corrections to rat-excludes * Apache should be truly appeased now * Ignore Relay parser files by name * Mark parser files as generated so they don't show up on Github * Add parsing helper function for tests * Mark parser files as not detectable
…ache#3043) * Add ability to load Prelude from disk * Port over id * Define compose * Linting errors and style changes * Eliminate unnecessary parens * Rename identType to typeIdent (makes more sense) * Another unnecessary paren * Bump the version number for the text format * Ensure .rly (Relay text files) are permitted * Correct release number and simplify grammar rule * Correct load_prelude docstring * Corrections to _parser * Add Apache headers to prelude source file * Remove test_prelude (redundant) * Correct misleading error message * Add check that parser is enabled in Prelude * Commit pre-generated parser, ensure generated files are treated as binaries, and have parser tests always fire * Permit parser files and git attributes files * Exclude gitattributes and parser files from apache check * Another attempt at appeasing Apache audit checker * Corrections to rat-excludes * Apache should be truly appeased now * Ignore Relay parser files by name * Mark parser files as generated so they don't show up on Github * Add parsing helper function for tests * Mark parser files as not detectable
The current Relay prelude is huge pain to modify and doesn't always result in correct ASTs requiring painful hand modifications each time we update it.
It would be far more useful to make use of the Relay parser to load the Prelude from disk.
This PR makes it possible to partially load a Relay Prelude from disk. The PR also includes some modifications to the Relay parser to support defining more code in Relay.
This should help motivate one piece of the final push on the Relay Text format (see #3016).
My goal is to make it possible to define a limited form of TensorArray using this in the coming days.
cc @wweic @joshpoll @MarisaKirisame